package com.tdcy.framework.util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
import net.sf.json.util.JSONUtils;

import com.tdcy.framework.util.json.DateJsonValueProcessor;

/**
 * JSON辅助类.
 */
public final class JsonUtils {
	/** The Constant jsonConfig. */
	private static final JsonConfig jsonConfig = new JsonConfig();

	/**
	 * Instantiates a new json helper.
	 */
	private JsonUtils() {

	}

	static {
		jsonConfig.registerJsonValueProcessor(java.util.Date.class, new DateJsonValueProcessor());
		jsonConfig.registerJsonValueProcessor(java.sql.Date.class, new DateJsonValueProcessor());
		jsonConfig.registerJsonValueProcessor(java.sql.Timestamp.class, new DateJsonValueProcessor());
	}

	/**
	 * 获取json配置对象.
	 * 
	 * @return the json config
	 */
	public static JsonConfig getJsonConfig() {
		return jsonConfig;
	}

	/**
	 * 转换对象到json字符串.
	 * 
	 * @param src
	 *            源代码
	 * @return json字符串
	 */
	public static String toJson(Object src) {
		if (src == null) {
			return "null";
		}

		if (JSONUtils.isArray(src)) {
			return JSONArray.fromObject(src, jsonConfig).toString();
		} else {
			return JSONObject.fromObject(src, jsonConfig).toString();
		}
	}

	/**
	 * 转换json字符串到map.
	 * 
	 * @param json
	 *            json字符串
	 * @return map对象
	 */
	public static Map<String, Object> toMap(String jsonstr) {
		Map<String, Object> map = new HashMap<String, Object>();
		// 最外层解析
		JSONObject json = JSONObject.fromObject(jsonstr);
		for (Object k : json.keySet()) {
			Object v = json.get(k);
			// 如果内层还是数组的话，继续解析
			if (v instanceof JSONArray) {
				List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
				Iterator<JSONObject> it = ((JSONArray) v).iterator();
				while (it.hasNext()) {
					JSONObject json2 = it.next();
					list.add(toMap(json2.toString()));
				}
				map.put(k.toString(), list);
			} else if (v instanceof JSONObject) {
				Map<String, Object> m = new HashMap<String, Object>();
				JSONObject obj = (JSONObject) v;
				for (Object o : obj.keySet()) {
					m.put((String) o, obj.get(o));
				}
				map.put(k.toString(), m);
			} else {
				map.put(k.toString(), v);
			}
		}
		return map;

		// return (Map<String, Object>)
		// JSONObject.toBean(JSONObject.fromObject(jsonstr), HashMap.class);
	}

	/**
	 * 转换json字符串到bean.
	 * 
	 * @param <T>
	 *            要转换的目标类型
	 * @param json
	 *            json字符串
	 * @param beanClass
	 *            bean类
	 * @return bean对象
	 */
	public static <T> T toBean(String json, Class<T> beanClass) {
		if (!StringUtils.hasText(json)) {
			return null;
		}

		return (T) JSONObject.toBean(JSONObject.fromObject(json), beanClass);
	}

	/**
	 * 转换json字符串到列表.
	 * 
	 * @param json
	 *            json字符串
	 * @return 列表对象
	 */
	public static List<Map<String, Object>> toList(String json) {
		if (!StringUtils.hasText(json)) {
			return null;
		}

		return (List<Map<String, Object>>) JSONArray.toCollection(JSONArray.fromObject(json), HashMap.class);
	}

	/**
	 * 转换json字符串到列表.
	 * 
	 * @param <T>
	 *            要转换的目标类型
	 * @param json
	 *            json字符串
	 * @param objectClass
	 *            对象类
	 * @return 列表对象
	 */
	public static <T> List<T> toList(String json, Class<T> objectClass) {
		if (!StringUtils.hasText(json)) {
			return null;
		}

		return (List<T>) JSONArray.toCollection(JSONArray.fromObject(json), objectClass);
	}

	public static String string2Json(String s) {
		if (StringUtils.isEmpty(s)) {
			return "";
		}
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < s.length(); i++) {
			char c = s.charAt(i);
			switch (c) {
			case '\"':
				sb.append("\\\"");
				break;
			case '\\':
				sb.append("\\\\");
				break;
			case '/':
				sb.append("\\/");
				break;
			case '\b':
				sb.append("\\b");
				break;
			case '\f':
				sb.append("\\f");
				break;
			case '\n':
				sb.append("\\n");
				break;
			case '\r':
				sb.append("\\r");
				break;
			case '\t':
				sb.append("\\t");
				break;
			default:
				sb.append(c);
			}
		}
		return sb.toString();
	}
}
